package com.hexinfo.dmpro.sparing.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.date.BetweenFormater;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUnit;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.io.file.FileAppender;
import cn.hutool.core.io.file.FileReader;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.hexinfo.dmpro.common.model.ClusterSparingConf;
import com.hexinfo.dmpro.common.utils.LogFileUtil;
import com.hexinfo.dmpro.common.utils.ScanCommonConstants;
import com.hexinfo.dmpro.sparing.dto.DateDataDTO;
import com.hexinfo.dmpro.sparing.dto.TableSyncConfDTO;
import com.hexinfo.dmpro.sparing.exception.ExecException;
import com.hexinfo.dmpro.sparing.model.HdfsHeatBackup;
import com.hexinfo.dmpro.sparing.model.HotStandbyTable;
import com.hexinfo.dmpro.sparing.model.TableSyncConf;
import com.hexinfo.dmpro.sparing.model.TimeFieldMatching;
import com.hexinfo.dmpro.sparing.service.ScanMetadataService;
import com.hexinfo.dmpro.sparing.service.TableSyncConfService;
import com.hexinfo.dmpro.sparing.service.TableSyncMethodService;
import com.hexinfo.dmpro.sparing.service.TimeFieldMatchingService;
import lombok.Cleanup;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;

import javax.sql.DataSource;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.Statement;
import java.util.*;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import java.util.stream.Collectors;


@Service
@Slf4j
@RequiredArgsConstructor(onConstructor_ = {@Lazy, @Autowired})
public class TableSyncMethodServiceImpl implements TableSyncMethodService {

    private final LogFileUtil logFileUtil;

    @Autowired
    @Qualifier("connPoolImpalaSource")
    private DataSource connPoolImpalaSource;
    @Autowired
    @Qualifier("connPoolHiveTarget")
    private DataSource connPoolHiveTarget;
    @Autowired
    @Qualifier("connPoolImpalaTarget")
    private DataSource connPoolImpalaTarget;

    //---------------------------------------------------时间过滤----------------------------------------------------
    /**
     * 获取重定向文件增量数据
     * @return
     */
    @Override
    public List<HdfsHeatBackup> gainFileData(String startTime, String endTime, String JQHdfsPrefix, String WGHdfsPrefix, String filePath) {
        DateTime cbRangeStartTime = DateUtil.parse(startTime);
        DateTime cbRangeEndTime = DateUtil.parse(endTime);
        List<HdfsHeatBackup> cbDataChangeList = new ArrayList<>();
        FileReader fileReader = new FileReader(filePath);
        List<String> hdfsPaths = fileReader.readLines();
        if (hdfsPaths == null || hdfsPaths.size() == 0) {
            return new ArrayList<>();
        }
        for (String hdfsPath : hdfsPaths) {
            boolean fileType = StrUtil.startWith(hdfsPath, "-");
            if (fileType) {
                int i = hdfsPath.indexOf(JQHdfsPrefix);
                String subTime = hdfsPath.substring(i - 17, i - 1);   //截取日期
                if (DateUtil.isIn(DateUtil.parse(subTime), cbRangeStartTime, cbRangeEndTime)) {
                    String subPath = hdfsPath.substring(i);
                    String hdfsFilePath = subPath.substring(0, subPath.lastIndexOf("/"));

                    HdfsHeatBackup cbDataChange = new HdfsHeatBackup();
                    cbDataChange.setSourceAddress(hdfsFilePath);
                    cbDataChange.setTargetAddress(hdfsFilePath.replace(JQHdfsPrefix, WGHdfsPrefix));
                    cbDataChangeList.add(cbDataChange);
                }
            }
        }
        //去重,去除同目录下有多个文件的情况
        List<HdfsHeatBackup> newList = cbDataChangeList.stream().collect(
                Collectors.collectingAndThen(Collectors.toCollection(() -> new TreeSet<HdfsHeatBackup>(
                        Comparator.comparing(HdfsHeatBackup::getSourceAddress)
                )), ArrayList::new));
        return newList;
    }

    /**
     * 执行shell脚本，只返回执行结果
     * @return
     */
    @Override
    public int execShellCode(String shell, FileAppender heatLog) {
        int exitValue = 0;
        try {
            Process ps = Runtime.getRuntime().exec(shell);
            exitValue = ps.waitFor();
            logFileUtil.appendLog(heatLog,"【"+exitValue+"】"+shell,false);
            if (exitValue != 0 && exitValue != 1){
                throw new ExecException("10001");
            }
        } catch (Exception e) {
            log.error("【异常】执行shell命令：{}",shell);
            log.error(e.getMessage(),e);
            logFileUtil.appendLog(heatLog,"【异常】【"+shell+"】："+e.getMessage(),false);
            throw new ExecException("10001");
        }
        return exitValue;
    }

    //---------------------------------------------------数据同步----------------------------------------------------
    /**
     * 执行shell脚本，只返回执行结果
     * @return
     */
    @Override
    public int execDistcpCode(String shell, FileAppender heatLog) {
        int exitValue = 0;
        try {
            Process ps = Runtime.getRuntime().exec(shell);
            exitValue = ps.waitFor();
            logFileUtil.appendLog(heatLog,"【"+exitValue+"】"+shell,false);
            if (exitValue != 0){
                throw new ExecException("10002");
            }
        } catch (Exception e) {
            log.error("【异常】执行shell命令：{}",shell);
            log.error(e.getMessage(),e);
            logFileUtil.appendLog(heatLog,"【异常】【"+shell+"】："+e.getMessage(),false);
            throw new ExecException("10002");
        }
        return exitValue;
    }

    //---------------------------------------------------刷目标表----------------------------------------------------
    /**
     * hive执行sql
     * @return
     */
    @Override
    public void execSqlHive(String setSql,String msckSql,FileAppender heatLog) {
        try{
            @Cleanup
            Connection connHive = connPoolHiveTarget.getConnection();
            @Cleanup
            Statement st = connHive.createStatement();
            //30分钟等待返回结果时长
            st.setQueryTimeout(1800);
            int iSet = st.executeUpdate(setSql);
            int i = st.executeUpdate(msckSql);
            logFileUtil.appendLog(heatLog,"【"+iSet+"】"+setSql,true);
            logFileUtil.appendLog(heatLog,"【"+i+"】"+msckSql,false);
        }catch (Exception e){
            log.error("【异常】"+msckSql);
            log.error(e.getMessage(),e);
            logFileUtil.appendLog(heatLog,"【异常】"+setSql,true);
            logFileUtil.appendLog(heatLog,"【异常】"+msckSql,true);
            logFileUtil.appendLog(heatLog,"【报错信息】"+e.getMessage(),false);
            throw new ExecException("10003");
        }
    }

    /**
     * impala刷新元数据
     */
    @Override
    public void refreshDataImpala(String sql,FileAppender heatLog) {
        try {
            @Cleanup
            Connection connImpala = connPoolImpalaTarget.getConnection();
            @Cleanup
            Statement st = connImpala.createStatement();
            //30分钟等待返回结果时长
            st.setQueryTimeout(1800);
            int i = st.executeUpdate(sql);
            logFileUtil.appendLog(heatLog,"【"+i+"】"+sql,false);
        } catch (Exception e) {
            if (e.getMessage().contains(ScanCommonConstants.ClusterName.TINP.value)){
                logFileUtil.appendLog(heatLog,"【忽略报错】该表没有分区字段"+e.getMessage(),false);
            }else {
                log.error("【异常】"+sql);
                log.error(e.getMessage(),e);
                logFileUtil.appendLog(heatLog,"【异常】"+sql,true);
                logFileUtil.appendLog(heatLog,"【报错信息】"+e.toString(),false);
                throw new ExecException("10003");
            }
        }
    }

    /**
     * impala执行sql
     * @return
     */
    @Override
    public void execSqlImpala(String sql,FileAppender heatLog) {
        try {
            @Cleanup
            Connection connImpala = connPoolImpalaTarget.getConnection();
            @Cleanup
            Statement st = connImpala.createStatement();
            //30分钟等待返回结果时长
            st.setQueryTimeout(1800);
            int i = st.executeUpdate(sql);
            logFileUtil.appendLog(heatLog,"【"+i+"】"+sql,false);
        } catch (Exception e) {
            log.error("【异常】"+sql);
            log.error(e.getMessage(),e);
            logFileUtil.appendLog(heatLog,"【异常】"+sql,true);
            logFileUtil.appendLog(heatLog,"【报错信息】"+e.toString(),false);
            throw new ExecException("10003");
        }
    }

    //---------------------------------------------------同步删除----------------------------------------------------
    private String dropBeyondSql = "alter table {} drop if exists partition (cast({} as string) = '{}' , cast({} as int) < {})";
    private String dropWithinSql = "alter table {} drop if exists partition (cast({} as string) = '{}' , cast({} as int) IN ({}))";
    private String selectAllDateSql = "SELECT {} FROM {} where 1=1 and cast({} as string) = '{}' and cast({} as int) between {} and {} GROUP BY {}";

    private String dropBeyondWYSql = "alter table {} drop if exists partition (cast({} as int) < {})";
    private String dropWithinWYSql = "alter table {} drop if exists partition (cast({} as int) IN ({}))";
    private String selectAllDateWYSql = "SELECT {} FROM {} where 1=1 and cast({} as int) between {} and {} GROUP BY {}";
    /**
     * 删除时间范围外的日期分区数据
     */
    @Override
    public void dropRangeBeyond(HotStandbyTable hotStandbyTable, Map<String, String> map,String dbTbName){
        try{
            if (hotStandbyTable.getSourceName().equals("无源")){
                logFileUtil.appendLog(hotStandbyTable.getHeatLog(),"源分区值：无源",true);
                String dropSql = StrUtil.format(dropBeyondWYSql,
                        dbTbName,
                        hotStandbyTable.getDatePartition(),
                        map.get("monthsAgo"));
                execSqlImpala(dropSql,hotStandbyTable.getHeatLog());
            }else {
                logFileUtil.appendLog(hotStandbyTable.getHeatLog(),"源分区值：" + hotStandbyTable.getSourceValue(),false);
                String[] split = hotStandbyTable.getSourceValue().split(",");
                for (String sourceValue : split) {
                    // alter table ods.table_name drop if exists partition (cast(bk_system as string) = 'OA' , cast(d_datadate as int) < 20220428)
                    String dropSql = StrUtil.format(dropBeyondSql,
                            dbTbName,
                            hotStandbyTable.getSourcePartition(),
                            sourceValue,
                            hotStandbyTable.getDatePartition(),
                            map.get("monthsAgo"));
                    execSqlImpala(dropSql,hotStandbyTable.getHeatLog());
                }
            }
        }catch (Exception e){
            log.error("【异常】删除时间范围外的日期分区数据");
            log.error(e.getMessage(),e);
            throw new ExecException("10004");
        }
    }

    /**
     * 删除源删除的时间范围内的日期分区数据
     */
    @Override
    public void dropRangeWithin(HotStandbyTable hotStandbyTable,Map<String, String> map,String dbTbName){
        try{
            if (hotStandbyTable.getSourceName().equals("无源")){
                //① 获取查询日期分区sql
                String selectSql = StrUtil.format(selectAllDateWYSql,
                        hotStandbyTable.getDatePartition(),
                        hotStandbyTable.getDbTbName(),
                        hotStandbyTable.getDatePartition(),
                        map.get("monthsAgo"),
                        map.get("monthsNow"),
                        hotStandbyTable.getDatePartition());
                String tarSelectSql = StrUtil.format(selectAllDateWYSql,
                        hotStandbyTable.getDatePartition(),
                        dbTbName,
                        hotStandbyTable.getDatePartition(),
                        map.get("monthsAgo"),
                        map.get("monthsNow"),
                        hotStandbyTable.getDatePartition());
                //② 获取日期分区数据
                @Cleanup
                Connection souImpalaConn = connPoolImpalaSource.getConnection();
                Set<String> souDate = selectDateTable(souImpalaConn, selectSql, hotStandbyTable.getDatePartition(), hotStandbyTable.getHeatLog());
                logFileUtil.appendLog(hotStandbyTable.getHeatLog(),"源日期分区数量："+souDate.size(),false);
                @Cleanup
                Connection tarImpalaConn = connPoolImpalaTarget.getConnection();
                Set<String> tarDate = selectDateTable(tarImpalaConn, tarSelectSql, hotStandbyTable.getDatePartition(), hotStandbyTable.getHeatLog());
                logFileUtil.appendLog(hotStandbyTable.getHeatLog(),"目标日期分区数量："+tarDate.size(),false);
                //③ 获取dropSql，执行sql
                String dropSql = getDropSql(souDate, tarDate, hotStandbyTable,dbTbName,"");
                if (StrUtil.isNotBlank(dropSql)){
                    execSqlImpala(dropSql,hotStandbyTable.getHeatLog());
                }
            }else {
                String[] split = hotStandbyTable.getSourceValue().split(",");
                for (String sourceValue : split) {
                    //① 获取查询日期分区sql
                    String selectSql = StrUtil.format(selectAllDateSql,
                            hotStandbyTable.getDatePartition(),
                            hotStandbyTable.getDbTbName(),
                            hotStandbyTable.getSourcePartition(),
                            sourceValue,
                            hotStandbyTable.getDatePartition(),
                            map.get("monthsAgo"),
                            map.get("monthsNow"),
                            hotStandbyTable.getDatePartition());
                    String tarSelectSql = StrUtil.format(selectAllDateSql,
                            hotStandbyTable.getDatePartition(),
                            dbTbName,
                            hotStandbyTable.getSourcePartition(),
                            sourceValue,
                            hotStandbyTable.getDatePartition(),
                            map.get("monthsAgo"),
                            map.get("monthsNow"),
                            hotStandbyTable.getDatePartition());
                    //② 获取日期分区数据
                    @Cleanup
                    Connection souImpalaConn = connPoolImpalaSource.getConnection();
                    Set<String> souDate = selectDateTable(souImpalaConn, selectSql, hotStandbyTable.getDatePartition(), hotStandbyTable.getHeatLog());
                    logFileUtil.appendLog(hotStandbyTable.getHeatLog(),"源日期分区数量："+souDate.size(),false);
                    @Cleanup
                    Connection tarImpalaConn = connPoolImpalaTarget.getConnection();
                    Set<String> tarDate = selectDateTable(tarImpalaConn, tarSelectSql, hotStandbyTable.getDatePartition(), hotStandbyTable.getHeatLog());
                    logFileUtil.appendLog(hotStandbyTable.getHeatLog(),"目标日期分区数量："+tarDate.size(),false);
                    //③ 获取dropSql，执行sql
                    String dropSql = getDropSql(souDate, tarDate, hotStandbyTable,dbTbName,sourceValue);
                    if (StrUtil.isNotBlank(dropSql)){
                        execSqlImpala(dropSql,hotStandbyTable.getHeatLog());
                    }
                }
            }
        }catch (Exception e){
            log.error("【异常】删除源删除的时间范围内的日期分区数据");
            log.error(e.getMessage(),e);
            throw new ExecException("10004");
        }
    }

    /**
     * 获取dropSql
     */
    private String getDropSql(Set<String> souDateValues, Set<String> tarDateValues,
                              HotStandbyTable hotStandbyTable,String dbTbName,String sourceValue) {
        String tarDropSql = "";
        tarDateValues.removeAll(souDateValues);
        if (tarDateValues.size() > 0){
            //  "alter table ods.acct_tprofitcurrent drop if exists partition (cast(srcsys as string) = 'HSTA4' , cast(d_cdate as int) IN (20211127,20211128,.....))"
            //拼接in中的参数
            String dates = "";
            for (String tarDateValue : tarDateValues) {
                if(!"NULL".equalsIgnoreCase(tarDateValue)){
                    dates += tarDateValue+",";
                }
            }
            String substring = dates.substring(0, dates.length()-1);
            if (hotStandbyTable.getSourceName().equals("无源")) {
                tarDropSql = StrUtil.format(dropWithinWYSql,
                        dbTbName,
                        hotStandbyTable.getDatePartition(),
                        substring);
            }else {
                tarDropSql = StrUtil.format(dropWithinSql,
                        dbTbName,
                        hotStandbyTable.getSourcePartition(),
                        sourceValue,
                        hotStandbyTable.getDatePartition(),
                        substring);
            }
        }else {
            logFileUtil.appendLog(hotStandbyTable.getHeatLog(),"【无需删除】目标表没有要删除的日期分区",false);
        }
        return tarDropSql;
    }

    /**
     * 查询每张表的日期分区
     */
    private Set<String> selectDateTable(Connection conn,String sql,String dateColName,FileAppender heatLog) throws Exception {
        Set<String> dateValues = new HashSet<>();
        try{
            @Cleanup
            Statement souSt = conn.createStatement();
            @Cleanup
            ResultSet resultSet = souSt.executeQuery(sql);
            //获取日期分区
            while (resultSet.next()) {
                dateValues.add(resultSet.getString(dateColName));
            }
            logFileUtil.appendLog(heatLog,sql,true);
        }catch (Exception e){
            log.error("【异常】"+sql);
            log.error(e.getMessage(),e);
            logFileUtil.appendLog(heatLog,"【异常】"+sql,true);
            logFileUtil.appendLog(heatLog,"【异常】"+e.getMessage(),false);
            throw new Exception(e.getMessage());
        }
        return dateValues;
    }

    //---------------------------------------------------数据比对----------------------------------------------------
    /**
     * 数据比对
     */
    private String selectSql = "select count(*) as count from {} where cast( {} as string ) = '{}' and cast( {} as int ) BETWEEN {} and {}";
    private String selectWYSql = "select count(*) as count from {} where cast( {} as int ) BETWEEN {} and {}";
    @Override
    public void dataCompare(HotStandbyTable hotStandbyTable,Map<String, String> map,String dbTbName){
        long souCountTotal = 0;
        long tarCountTotal = 0;
        try{
            if (hotStandbyTable.getSourceName().equals("无源")){
                logFileUtil.appendLog(hotStandbyTable.getHeatLog(),"源分区值：无源",true);
                String sql = StrUtil.format(selectWYSql,
                        hotStandbyTable.getDbTbName(),
                        hotStandbyTable.getDatePartition(),
                        map.get("monthsAgo"),
                        map.get("monthsNow"));
                String tarSql = StrUtil.format(selectWYSql,
                        dbTbName,
                        hotStandbyTable.getDatePartition(),
                        map.get("monthsAgo"),
                        map.get("monthsNow"));
                @Cleanup
                Connection souImpalaConn = connPoolImpalaSource.getConnection();
                Set<String> souSet = selectDateTable(souImpalaConn, sql, "count", hotStandbyTable.getHeatLog());
                @Cleanup
                Connection tarImpalaConn = connPoolImpalaTarget.getConnection();
                Set<String> tarSet = selectDateTable(tarImpalaConn, tarSql, "count", hotStandbyTable.getHeatLog());
                String souCount = new ArrayList<>(souSet).get(0);
                String tarCount = new ArrayList<>(tarSet).get(0);
                souCountTotal += Long.parseLong(souCount);
                tarCountTotal += Long.parseLong(tarCount);
            }else {
                logFileUtil.appendLog(hotStandbyTable.getHeatLog(),"源分区值：" + hotStandbyTable.getSourceValue(),true);
                String[] split = hotStandbyTable.getSourceValue().split(",");
                for (String sourceValue : split) {
                    // select count(*) {} where cast( bk_system as string ) = 'YEBHB' and cast( d_datadate as int ) BETWEEN 20211109 and 20231110
                    String sql = StrUtil.format(selectSql,
                            hotStandbyTable.getDbTbName(),
                            hotStandbyTable.getSourcePartition(),
                            sourceValue,
                            hotStandbyTable.getDatePartition(),
                            map.get("monthsAgo"),
                            map.get("monthsNow"));
                    String tarSql = StrUtil.format(selectSql,
                            dbTbName,
                            hotStandbyTable.getSourcePartition(),
                            sourceValue,
                            hotStandbyTable.getDatePartition(),
                            map.get("monthsAgo"),
                            map.get("monthsNow"));
                    @Cleanup
                    Connection souImpalaConn = connPoolImpalaSource.getConnection();
                    Set<String> souSet = selectDateTable(souImpalaConn, sql, "count", hotStandbyTable.getHeatLog());
                    @Cleanup
                    Connection tarImpalaConn = connPoolImpalaTarget.getConnection();
                    Set<String> tarSet = selectDateTable(tarImpalaConn, tarSql, "count", hotStandbyTable.getHeatLog());
                    String souCount = new ArrayList<>(souSet).get(0);
                    String tarCount = new ArrayList<>(tarSet).get(0);
                    souCountTotal += Long.parseLong(souCount);
                    tarCountTotal += Long.parseLong(tarCount);
                    logFileUtil.appendLog(hotStandbyTable.getHeatLog(),"源count大小："+souCount+"，目标count大小："+tarCount,false);
                }
            }
            if (souCountTotal == tarCountTotal){
                logFileUtil.appendLog(hotStandbyTable.getHeatLog(),"【比对成功】count总大小："+souCountTotal,false);
            }else {
                logFileUtil.appendLog(hotStandbyTable.getHeatLog(),"【比对失败】源count总大小："+souCountTotal+"，目标count总大小："+tarCountTotal,false);
                throw new ExecException("10005");
            }
        }catch (ExecException e){
            throw new ExecException("10005");
        }catch (Exception e){
            log.error("【异常】获取count总数异常");
            log.error(e.getMessage(),e);
            logFileUtil.appendLog(hotStandbyTable.getHeatLog(),"【异常】获取count总数异常："+e.getMessage(),false);
            throw new ExecException("10005");
        }finally {
            //修改任务信息
            updateHotStandbyTable(hotStandbyTable,souCountTotal,tarCountTotal);
        }
    }

    /**
     * 修改热备表信息
     */
    public void updateHotStandbyTable(HotStandbyTable hotStandbyTable,Long souCountTotal,Long tarCountTotal) {
        String format = DateUtil.format(DateUtil.date(), "yyyy-MM-dd HH:mm:ss");
        String timeData = hotStandbyTable.getHotStandbyTimeData()+ format;
        Map<String, Object> timeStr = getTimeStr(timeData);
        String logData = (String) timeStr.get("logData");
        long countTime = (long) timeStr.get("countTime");
        hotStandbyTable.setHotStandbyTimeData("----------------------模块耗时---------------------"+ "\n"+ logData
                +"-----------------开始时间--结束时间-----------------"+ "\n" + timeData);
        hotStandbyTable.setHotStandbyTime(DateUtil.formatBetween(DateUtil.offsetSecond(DateUtil.date(),(int)-countTime),DateUtil.date(), BetweenFormater.Level.SECOND));
        hotStandbyTable.setEndTime(format);
        hotStandbyTable.setTaskState(ScanCommonConstants.ClusterName.YWC.value);
        hotStandbyTable.setSourceCountNumber(souCountTotal);
        hotStandbyTable.setTargetCountNumber(tarCountTotal);
    }

    public Map<String,Object> getTimeStr(String strTimeData) {
        String str = "";
        long count = 0L;
        Map<String,Object> map = new HashMap<>();
        String[] split = strTimeData.split("\n");
        for (String s : split) {
            if (s.length()>6){
                String[] split1 = s.substring(6).split("--");
                if (split1.length == 2){
                    long betweenDay = DateUtil.between(DateUtil.parse(split1[0]), DateUtil.parse(split1[1]), DateUnit.SECOND);
                    count += betweenDay;
                    str += s.substring(0,6)+DateUtil.formatBetween(DateUtil.parse(split1[0]), DateUtil.parse(split1[1]), BetweenFormater.Level.SECOND) +"\n";
                }
            }
        }
        map.put("logData",str);
        map.put("countTime",count);
        return map;
    }

    //-------------------------------------------------------------------------
    /**
     * 判断所有获取是否全部完成
     * List<Future<Boolean>>
     */
    @Override
    public Boolean futureStatus(List<Future<Boolean>> futures, Integer threadMonitoring){
        Boolean tableStatus = true;
        //会等待所有线程都执行结束，拿到结果
        for (Future<Boolean> future : futures) {
            try {
                Object obj = future.get(threadMonitoring, TimeUnit.SECONDS); // 等待3小时
                Boolean aBoolean = future.get();
                if (!aBoolean){
                    tableStatus = false;
                }
                // 处理任务结果
            } catch (InterruptedException e) {
                // 当前线程被中断
                tableStatus = false;
                log.error("线程中断", e);
            } catch (ExecutionException e) {
                // 处理任务执行异常
                tableStatus = false;
                log.error("线程执行异常", e.getCause());// 获取实际的异常原因
            } catch (TimeoutException e) {
                // 等待超时
                tableStatus = false;
                log.error("线程超时", e);
                future.cancel(true); // 取消任务执行
            }
        }
        return tableStatus;
    }


}
